

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Python中的多线程 - cxp&#39;s blog</title>
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="google" content="notranslate" />

  
  
  <meta name="description" content=" 多线程、多进程


概念

进程：计算机中需要执行的..."> 
  
  <meta name="author" content="Alex"> 

  
    <link rel="icon" href="/images/icons/favicon-16x16.png" type="image/png" sizes="16x16">
  
  
    <link rel="icon" href="/images/icons/favicon-32x32.png" type="image/png" sizes="32x32">
  
  
    <link rel="apple-touch-icon" href="/images/icons/apple-touch-icon.png" sizes="180x180">
  
  
    <meta rel="mask-icon" href="/images/icons/stun-logo.svg" color="#333333">
  
  
    <meta rel="msapplication-TileImage" content="/images/icons/favicon-144x144.png">
    <meta rel="msapplication-TileColor" content="#000000">
  

  <link rel="stylesheet" href="/css/style.css">

  
  <link rel="stylesheet" href="//at.alicdn.com/t/font_1445822_h1619vhl1nr.css">
  

  
  
  <link rel="stylesheet" href="https://cdn.bootcss.com/fancybox/3.5.7/jquery.fancybox.min.css">
  

  
  
  <link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/9.18.1/styles/xcode.min.css">
  

  <script>
    var CONFIG = window.CONFIG || {};
    var ZHAOO = window.ZHAOO || {};
    CONFIG = {
      isHome: false,
      fancybox: true,
      pjax: false,
      lazyload: {
        enable: true,
        loadingImage: '',
      },
      donate: {
        enable: true,
        alipay: 'https://pic.izhaoo.com/alipay.jpg',
        wechat: 'https://pic.izhaoo.com/wechat.jpg'
      },
      motto: {
        api: '',
        default: '我在开了灯的床头下，想问问自己的心啊。'
      },
      galleries: {
        enable: true
      },
      fab: {
        enable: true,
        alwaysShow: false
      },
      carrier: {
        enable: true
      },
      daovoice: {
        enable: true
      }
    }
  </script>

  

  
<link rel="alternate" href="/atom.xml" title="cxp's blog" type="application/atom+xml">
</head>
<body class="lock-screen">
  <div class="loading"></div>
  


<nav class="navbar">
  <div class="left"></div>
  <div class="center">Python中的多线程</div>
  <div class="right">
    <i class="iconfont iconmenu j-navbar-menu"></i>
  </div>
</nav>

  <nav class="menu">
  <div class="menu-wrap">
    <div class="menu-close">
      <i class="iconfont iconbaseline-close-px"></i>
    </div>
    <ul class="menu-content">
      
      
      
      
      <li class="menu-item"><a href="/ " class="underline"> 首页</a></li>
      
      
      
      
      <li class="menu-item"><a href="/galleries " class="underline"> 摄影</a></li>
      
      
      
      
      <li class="menu-item"><a href="/archives " class="underline"> 归档</a></li>
      
      
      
      
      <li class="menu-item"><a href="/tags " class="underline"> 标签</a></li>
      
      
      
      
      <li class="menu-item"><a href="/categories " class="underline"> 分类</a></li>
      
      
      
      
      <li class="menu-item"><a href="/about " class="underline"> 关于</a></li>
      
    </ul>
    <div class="menu-copyright"><p>Powered by <a target="_blank" href="https://hexo.io">Hexo</a>  |  Theme - <a target="_blank" href="https://github.com/izhaoo/hexo-theme-zhaoo">zhaoo</a></p></div>
  </div>
</nav>
  <main id="main">
  <div class="container" id="container">
    <article class="article">
  <div class="wrap">
    <section class="head">
  <img   class="lazyload" data-original="/images/theme/post-image.jpg" src=""  draggable="false">
  <div class="head-mask">
    <h1 class="head-title">Python中的多线程</h1>
    <div class="head-info">
      <span class="post-info-item"><i class="iconfont iconcalendar"></i>四月 02, 2019</span
        class="post-info-item">
      
      <span class="post-info-item"><i class="iconfont iconfont-size"></i>1956</span>
    </div>
  </div>
</section>
    <section class="main">
      <section class="content">
        <h1 id="多线程-多进程"><a class="markdownIt-Anchor" href="#多线程-多进程"></a> 多线程、多进程</h1>
<ol>
<li>
<p>概念</p>
<ul>
<li>进程：计算机中需要执行的任务称之为进程，比如浏览器的运行、播放音乐。可以通过fork和spawn派生出新的进程来执行其他任务。进程间通过进程间通信方式进行通信。</li>
<li>线程：进程中，需要完成的一个多个任务称之为线程，共享相同的上下文，被称之为迷你进程。比如播放音乐中需要输出歌词和音频。同一进程下线程间时共享数据空间。</li>
</ul>
</li>
</ol>
<ul>
<li>
<p>让步：线程中有指令指针，当其他的线程进行时，指针可以被抢占和挂起。</p>
</li>
<li>
<p>竞态条件：多个线程访问同一片数据，访问顺序不同可能造成的结果不同。</p>
<p>进程和线程都是执行多任务的实现方法。</p>
</li>
</ul>
<ol start="2">
<li>
<p>实现多任务的方式</p>
<p>采用以下三种方式：</p>
</li>
</ol>
<ul>
<li>多进程</li>
<li>多线程</li>
<li>多进程中多线程（较为复杂，使用较少）</li>
</ul>
<ol start="3">
<li>
<p>多线程的适用类型</p>
<p>适用于的任务类型：</p>
</li>
</ol>
<ul>
<li>
<p>本质是异步</p>
</li>
<li>
<p>多个并发</p>
</li>
<li>
<p>根据应用需求，执行顺序不确定</p>
<p>根据应用的不同，子任务可能需要先运算出中间结果，在合并为最终结果。</p>
<p>计算密集型/IO密集型</p>
</li>
<li>
<p>计算密集型任务的特点是要进行大量的计算，消耗CPU资源，靠CPU的运算能力。这种任务一般需要高效利用CPU，对于代码的执行效率要求很高，可以设置同时进行的任务数为CPU的核心数。</p>
</li>
<li>
<p>IO密集型，涉及到网络、磁盘IO的任务，这种任务的大部分时间都在等待IO操作完成（因为IO的速度远远低于CPU和内存的速度）。对于IO密集型任务，任务越多，CPU效率越高，但也有一个限度。常见的大部分任务都是IO密集型任务，比如Web应用。对于IO密集型任务，最合适的语言就是开发效率最高（代码量最少）的语言，脚本语言是首选，C语言最差。</p>
<p>在Python中由于代码是在Python虚拟机中执行（解释器主循环），而主循环中只允许同时只有一个线程运行，对虚拟机的访问时利用全局解释器锁GIL控制的，所以在Python中多线程更适合IO密集型任务。</p>
</li>
</ul>
<ol start="4">
<li>
<p>多线程能提高系统的性能</p>
<p>通过适用多线程编程可以通过将复杂问题简化，比如将编程任务规划成几个特定函数的线程。个线程之间功能明确、清晰。</p>
</li>
</ol>
<ul>
<li>UserRequestThread：读取输入</li>
<li>RequestProcessor：根据输入处理请求</li>
<li>ReplyThread：向用户输出</li>
</ul>
<h2 id="python解释器执行流程"><a class="markdownIt-Anchor" href="#python解释器执行流程"></a> Python解释器执行流程：</h2>
<ul>
<li>
<p>设置GIL</p>
</li>
<li>
<p>切换到一个线程执行</p>
</li>
<li>
<ol>
<li>指定数量的字节码指令</li>
<li>线程让出控制权time.sleep()</li>
</ol>
</li>
<li>
<p>切换出线程</p>
</li>
<li>
<p>解锁GIL</p>
</li>
<li>
<p>重复以上步骤</p>
</li>
</ul>
<h2 id="_thread-threading"><a class="markdownIt-Anchor" href="#_thread-threading"></a> _thread、threading</h2>
<p>Python中实现多线程使用到的模块为_thread和threading模块，Python核心编程中建议使用threading，他们之间的差别是：</p>
<ul>
<li>前者更为底层基础，后者功能更加丰富，有着更多的同步原语可供操作</li>
<li>前者对于进程何时退出没有控制，当主线程结束时，其他线程也将结束，并没有警告；后者能够保证重要的子线程在进程退出前结束</li>
<li>前者不支持守护进程daemon，所谓的守护进程通常是指的一些不重要的进程一般是等待客户端请求服务的服务器，当主线程想要结束，不需要等待子线程的结束，那么可以吧这些线程设置为守护进程。</li>
<li>其实Python3中都把thread改为_thread了，也就是建议用户尽量使用threading模块了。</li>
</ul>
<p>多线程应用编程中可能需要使用的模块：</p>
<ul>
<li>_thread</li>
<li>threading</li>
<li>multiprocessing</li>
<li>subprocess</li>
<li>Queue</li>
<li>mutex：互斥对象</li>
<li>concurrent.futures</li>
<li>SocketServer：创建/管理线程控制的TCP/UDP服务器</li>
</ul>
<h2 id="threading中的对象"><a class="markdownIt-Anchor" href="#threading中的对象"></a> threading中的对象</h2>
<ul>
<li>Thread</li>
<li>Lock</li>
<li>RLock</li>
<li>Condition</li>
<li>Event</li>
<li>Timer</li>
<li>Semaphore：为线程间共享的有限资源提供一个“计数器”，没有可用资源时被阻塞</li>
<li>BoundedSemaphore：与上面不同的是不允许超过初始值</li>
<li>Barrier：创建一个“障碍”，必须达到指定数量线程后才能继续</li>
</ul>
<p>Thread类</p>
<ul>
<li>name</li>
<li>ident</li>
<li>daemon：守护进程的标识</li>
<li>start()</li>
<li>run()：定义线程功能的方法。创建子类时，被用户重写</li>
<li>join()</li>
<li>__ init __(group=None, target= None, name=None,args=None,kwargs={}, verbose=None,daemon=None)</li>
</ul>
<p>使用Thread类，来创建线程的方式：</p>
<ul>
<li>创建Thread实例，并向它传入一个函数</li>
<li>创建Thread实例，并向它传递可调用的类实例</li>
<li>派生Thread的子类，并创建子类的实例</li>
</ul>
<p>上面三种一般是采用第一种和第三种，第三种更加符合面向对象的接口设计。</p>

      </section>
      <section class="extra">
        
        <ul class="copyright">
  
  <li><strong>本文作者：</strong>Alex</li>
  <li><strong>本文链接：</strong><a href="https://cxpeng.cn/archives/949db3a1.html">https://cxpeng.cn/archives/949db3a1.html</a></li>
  <li><strong>版权声明：</strong>本博客所有文章均采用<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh"
      rel="external nofollow" target="_blank"> BY-NC-SA </a>许可协议，转载请注明出处！</li>
  
</ul>
        
        
        <section class="donate">
  <div class="qrcode">
    <img   class="lazyload" data-original="https://pic.izhaoo.com/alipay.jpg" src="" >
  </div>
  <div class="icon">
    <a href="javascript:;" target="_blank" rel="noopener" id="alipay"><i class="iconfont iconalipay"></i></a>
    <a href="javascript:;" target="_blank" rel="noopener" id="wechat"><i class="iconfont iconwechat-fill"></i></a>
  </div>
</section>
        
        
  <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Python/" rel="tag">Python</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" rel="tag">多线程</a></li></ul>

        
<nav class="nav">
  
    <a href="/archives/749620d3.html"><i class="iconfont iconleft"></i>360在线笔试编程题</a>
  
  
    <a href="/archives/7fd01c5b.html">怎么样使用Git？<i class="iconfont iconright"></i></a>
  
</nav>

      </section>
      
      <section class="comments">
  
  <div class="btn" id="comments-btn">查看评论</div>
  
  
</section>
      
    </section>
  </div>
</article>
  </div>
</main>
  <footer class="footer">
  <div class="footer-social">
    
    
    
    
    
    <a href="tencent://message/?Menu=yes&uin=894519210 " target="_blank" onMouseOver="this.style.color= '#12B7F5'"
      onMouseOut="this.style.color='#33333D'">
      <i class="iconfont footer-social-item  iconQQ "></i>
    </a>
    
    
    
    
    
    <a href="javascript:; " target="_blank" onMouseOver="this.style.color= '#09BB07'"
      onMouseOut="this.style.color='#33333D'">
      <i class="iconfont footer-social-item  iconwechat-fill "></i>
    </a>
    
    
    
    
    
    <a href="https://www.instagram.com/izhaoo/ " target="_blank" onMouseOver="this.style.color= '#DA2E76'"
      onMouseOut="this.style.color='#33333D'">
      <i class="iconfont footer-social-item  iconinstagram "></i>
    </a>
    
    
    
    
    
    <a href="https://github.com/izhaoo " target="_blank" onMouseOver="this.style.color= '#24292E'"
      onMouseOut="this.style.color='#33333D'">
      <i class="iconfont footer-social-item  icongithub-fill "></i>
    </a>
    
    
    
    
    
    <a href="mailto:izhaoo@163.com " target="_blank" onMouseOver="this.style.color='#FFBE5B'"
      onMouseOut="this.style.color='#33333D'">
      <i class="iconfont footer-social-item  iconmail"></i>
    </a>
    
  </div>
  <div class="footer-copyright"><p>Powered by <a target="_blank" href="https://hexo.io">Hexo</a>  |  Theme - <a target="_blank" href="https://github.com/izhaoo/hexo-theme-zhaoo">zhaoo</a></p></div>
</footer>
  
      <div class="fab fab-plus">
    <i class="iconfont iconplus"></i>
  </div>
  
  <div class="fab fab-daovoice">
    <i class="iconfont iconcomment"></i>
  </div>
  
  <div class="fab fab-up">
    <i class="iconfont iconcaret-up"></i>
  </div>
  
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</body>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>




<script src="https://cdn.bootcdn.net/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script>




<script src="https://cdn.bootcss.com/fancybox/3.5.7/jquery.fancybox.min.js"></script>




<script src="/js/utils.js"></script>
<script src="/js/modules.js"></script>
<script src="/js/zui.js"></script>
<script src="/js/script.js"></script>




<script>
  (function (i, s, o, g, r, a, m) {
    i["DaoVoiceObject"] = r;
    i[r] = i[r] || function () {
      (i[r].q = i[r].q || []).push(arguments)
    }, i[r].l = 1 * new Date();
    a = s.createElement(o), m = s.getElementsByTagName(o)[0];
    a.async = 1;
    a.src = g;
    a.charset = "utf-8";
    m.parentNode.insertBefore(a, m)
  })(window, document, "script", ('https:' == document.location.protocol ? 'https:' : 'http:') +
    "//widget.daovoice.io/widget/0f81ff2f.js", "daovoice")
  daovoice('init', {
    app_id: "abcdefg"
  }, {
    launcher: {
      disableLauncherIcon: true,
    },
  });
  daovoice('update');
</script>



<script>
  (function () {
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
      bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
    } else {
      bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
  })();
</script>


<script>
  var _hmt = _hmt || [];
  (function () {
    var hm = document.createElement("script");
    hm.src = "https://hm.baidu.com/hm.js?4c204d8bc027a0455b5fc642ac334ca8";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
  })();
</script>










</html>